func printValue[T any](val T) { var s Stringer if v, ok := any(val).(Stringer); ok { s = v } if s != nil { fmt.Println("Stringer:", s.String()) } else { fmt.Println("Default:", val) } }
func main() { var x MyInt = 5 printValue(x) printValue(10) }
❓Вопрос: Что будет напечатано? Почему результат может удивить даже опытных Go-разработчиков?
🔍Разбор: Этот код использует generics и проверяет, реализует ли val интерфейс Stringer.
Пошагово:
1️⃣var x MyInt = 5 Тип MyInt реализует интерфейс Stringer через метод:
```go func (m MyInt) String() string { ... } ```
2️⃣printValue(x) - val здесь типа MyInt. - В строке: any(val).(Stringer) - Приведение типа успешно, потому что MyInt реализует Stringer. - Печатается: ``` Stringer: MyInt: 5 ```
3️⃣printValue(10) - Тип val здесь int. - intне реализуетStringer. - Приведение any(val).(Stringer) не срабатывает (ok == false). - Печатается: ``` Default: 10 ```
✅Ожидаемый вывод:
``` Stringer: MyInt: 5 Default: 10 ```
💥Подвох:
- Даже если MyInt — это просто int, метод String()делает его другим типом, который реализует интерфейс. - Многие забывают, что встроенные типы (int, string, и т.д.) никогда не реализуют интерфейсы напрямую, даже если они похожи на пользовательские типы. - Ключевой момент: any(val) оборачивает значение в интерфейс{}, поэтому приведение типа срабатывает только если исходный тип действительно реализует интерфейс.
🆕Почему это актуально для Go 1.24:
Generics в Go 1.22+ улучшились по типовой проверке и стали более гибкими. Go 1.24 сделал generics более стабильными и оптимизированными, но все еще важно понимать различия между типами и интерфейсами, особенно при работе с any и приведения типов внутри параметризованных функций.
🛡️Лайфхак:
Если вы хотите печатать всё одинаково для типов с String(), можно сделать generic-констрейн с интерфейсом:
Generics упрощают код, но внимательность к типам и их интерфейсам критически важна. Даже небольшие различия между int и MyInt влияют на поведение программы.
func printValue[T any](val T) { var s Stringer if v, ok := any(val).(Stringer); ok { s = v } if s != nil { fmt.Println("Stringer:", s.String()) } else { fmt.Println("Default:", val) } }
func main() { var x MyInt = 5 printValue(x) printValue(10) }
❓Вопрос: Что будет напечатано? Почему результат может удивить даже опытных Go-разработчиков?
🔍Разбор: Этот код использует generics и проверяет, реализует ли val интерфейс Stringer.
Пошагово:
1️⃣var x MyInt = 5 Тип MyInt реализует интерфейс Stringer через метод:
```go func (m MyInt) String() string { ... } ```
2️⃣printValue(x) - val здесь типа MyInt. - В строке: any(val).(Stringer) - Приведение типа успешно, потому что MyInt реализует Stringer. - Печатается: ``` Stringer: MyInt: 5 ```
3️⃣printValue(10) - Тип val здесь int. - intне реализуетStringer. - Приведение any(val).(Stringer) не срабатывает (ok == false). - Печатается: ``` Default: 10 ```
✅Ожидаемый вывод:
``` Stringer: MyInt: 5 Default: 10 ```
💥Подвох:
- Даже если MyInt — это просто int, метод String()делает его другим типом, который реализует интерфейс. - Многие забывают, что встроенные типы (int, string, и т.д.) никогда не реализуют интерфейсы напрямую, даже если они похожи на пользовательские типы. - Ключевой момент: any(val) оборачивает значение в интерфейс{}, поэтому приведение типа срабатывает только если исходный тип действительно реализует интерфейс.
🆕Почему это актуально для Go 1.24:
Generics в Go 1.22+ улучшились по типовой проверке и стали более гибкими. Go 1.24 сделал generics более стабильными и оптимизированными, но все еще важно понимать различия между типами и интерфейсами, особенно при работе с any и приведения типов внутри параметризованных функций.
🛡️Лайфхак:
Если вы хотите печатать всё одинаково для типов с String(), можно сделать generic-констрейн с интерфейсом:
Generics упрощают код, но внимательность к типам и их интерфейсам критически важна. Даже небольшие различия между int и MyInt влияют на поведение программы.
BY Go tests
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
That strategy is the acquisition of a value-priced company by a growth company. Using the growth company's higher-priced stock for the acquisition can produce outsized revenue and earnings growth. Even better is the use of cash, particularly in a growth period when financial aggressiveness is accepted and even positively viewed.he key public rationale behind this strategy is synergy - the 1+1=3 view. In many cases, synergy does occur and is valuable. However, in other cases, particularly as the strategy gains popularity, it doesn't. Joining two different organizations, workforces and cultures is a challenge. Simply putting two separate organizations together necessarily creates disruptions and conflicts that can undermine both operations.
Among the actives, Ascendas REIT sank 0.64 percent, while CapitaLand Integrated Commercial Trust plummeted 1.42 percent, City Developments plunged 1.12 percent, Dairy Farm International tumbled 0.86 percent, DBS Group skidded 0.68 percent, Genting Singapore retreated 0.67 percent, Hongkong Land climbed 1.30 percent, Mapletree Commercial Trust lost 0.47 percent, Mapletree Logistics Trust tanked 0.95 percent, Oversea-Chinese Banking Corporation dropped 0.61 percent, SATS rose 0.24 percent, SembCorp Industries shed 0.54 percent, Singapore Airlines surrendered 0.79 percent, Singapore Exchange slid 0.30 percent, Singapore Press Holdings declined 1.03 percent, Singapore Technologies Engineering dipped 0.26 percent, SingTel advanced 0.81 percent, United Overseas Bank fell 0.39 percent, Wilmar International eased 0.24 percent, Yangzijiang Shipbuilding jumped 1.42 percent and Keppel Corp, Thai Beverage, CapitaLand and Comfort DelGro were unchanged.